/*
write by hasaki
first edit on 2019-6-28
last change on 2019-6-29
golang写的gateio交易所连接，包括restful请求和websocket请求
*/
package gateio
import (
	"fmt"
	"net/http"
	"io/ioutil"
	"strings"
)

// gateio交易所api地址结构体
type URL struct{
	BaseDataUrl string
	BaseTradeUrl string
}

// 当作类来使用的gateio结构体
type Gateio struct{
	Url URL
}

// 初始化api地址
func (g *Gateio) initURL(){
	g.Url.BaseDataUrl="https://data.gateio.io/api2/1/"
	g.Url.BaseTradeUrl="https://api.gateio.io/api2/1/private/"
}

// 从gate交易所获取所有交易对
func (g *Gateio) getThePairs(){
	url	:=g.Url.BaseDataUrl+"pairs"
	res,err:=http.Get(url)
	
	if err!=nil{
		fmt.Println("请求网址交易对返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求交易对正确返回",string(body))
}

// 请求订单参数，交易费用，最小下单量，价格精度
func (g *Gateio) getTheContracts(){
	url:=g.Url.BaseDataUrl+"marketinfo"
	res,err:=http.Get(url)
	
	if err!=nil{
		fmt.Println("请求订单信息网址返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求订单信息正确返回",string(body))
}

// 请求币种信息，充值，体现，交易状态
func (g *Gateio) getCoinInfo() {
	url:=g.Url.BaseDataUrl+"coininfo"
	res,err:=http.Get(url)
	
	if err!=nil{
		fmt.Println("请求币种信息网址返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求币种信息正确返回",string(body))
}

// tick行情接口
func (g *Gateio) getTick(symbol string){
	// baseVolume: 交易量
	// high24hr:24小时最高价
	// highestBid:买方最高价
	// last:最新成交价
	// low24hr:24小时最低价
	// lowestAsk:卖方最低价
	// percentChange:涨跌百分比
	// quoteVolume: 兑换货币交易量
	url:=g.Url.BaseDataUrl+"ticker/"+symbol
	res,err:=http.Get(url)
	
	if err!=nil{
		fmt.Println("请求tick网址返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求tick正确返回",string(body))
}

// 深度行情接口
func (g *Gateio) getDepth(symbol string){
	// {
    //     "result": "true",
    //     "asks": [
    //             [29500,    4.07172355],
    //             [29499,    0.00203397],
    //             [29495,    1],
    //             [29488,    0.0672],
    //             [29475,    0.001]
    //         ],
    //     "bids": [
    //             [28001, 0.0477],
    //             [28000, 0.35714018],
    //             [28000, 2.56222976],
    //             [27800, 0.0015],
    //             [27777, 0.1]
    //         ]
    //     }

	url:=g.Url.BaseDataUrl+"orderBook/"
	res,err:=http.Get(url)
	
	if err!=nil{
		fmt.Println("请求tick网址返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求tick正确返回",string(body))
}


// 获取最近时间内的K线数据
func (g *Gateio) getKLine(symbol string){
	// 默认是拿去最大的历史数据 symbol的示例：btc_usdt
	// {
	// 	"result": "true",
	// 	"data": [
	// 		[1524556800000, 12.8756391686, 9266.02, 9266.21, 9231.01, 9233.99],
	// 		[1524558600000, 18.3153691562, 9255.79, 9284, 9251.01, 9252],
	// 		[1524560400000, 17.5693326481, 9255, 9290.37, 9238.89, 9255.79],
	// 		[1524562200000, 13.0314933662, 9281.92, 9295, 9239, 9255.4],
	// 		[1524564000000, 26.0352948098, 9290.92, 9327.46, 9282, 9282],
	// 		[1524565800000, 24.5813921079, 9300, 9340, 9290, 9297.5],
	// 		[1524567600000, 27.8742949471, 9345, 9348.99, 9291.91, 9300],
	// 		[1524569400000, 29.3344591996, 9299.99, 9349.99, 9290, 9343.93],
	// 		[1524571200000, 28.4720072519, 9305, 9327.99, 9286.32, 9290.02],
	// 		...
	// 	]
	// }

	url:=g.Url.BaseDataUrl+"candlestick2/"+symbol+"?group_sec=60&range_hour=24"
	res,err:=http.Get(url)
	
	if err!=nil{
		fmt.Println("请求过去24小时一分钟K线网址返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求过去24小时一分钟K线正确返回",string(body))
}


// C2C交易市场深度
func (g *Gateio)c2cDepth(){
	// 相对于获取汇率行情
	// {
	// 	"result": "true",
	// 	"asks": [
	// 		["6.86", "306.1114", "100.0000", "30000.0000"],
	// 		["6.86", "808.0467", "100.0000", "4220.0000"],
	// 		["6.86", "12922.3622", "200.0000", "24131.4000"],
	// 		["6.86", "4412.0000", "300.0000", "4412.0000"]
	// 	],
	// 	"bids": [
	// 		["6.84", "3654.9707", "3654.0000", "3654.9700"],
	// 		["6.84", "17487.1700", "1500.0000", "30000.0000"],
	// 		["6.84", "21.1317", "20.0000", "1461.9883"],
	// 		["6.83", "27846.0000", "800.0000", "30000.0000"]
	// 	]
	// },
	url:=g.Url.BaseDataUrl+"orderBook_c2c/usdt_cny"
	res,err:=http.Get(url)
	
	if err!=nil{
		fmt.Println("请求c2c深度网址返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求c2c深度正确返回",string(body))
}

// -------------------------------------- 交易部分---------------------------------
// 用户首先要通过这个链接获取API接口身份认证用到的Key和Secret。然后在程序中用Secret作为密码，
// 通过SHA512加密方式签名需要POST给服务器的数据得到Sign，并在HTTPS请求的Header部分传回Key和Sign。
// 获取账户资金余额
func (g *Gateio)getBalance(){
	// {
    //     "result": "true",
    //     "available": {
    //         "BTC": "1000",
    //         "ETH": "968.8",
    //         "ETC": "0",
    //         },
    //     "locked": {
    //         "ETH": "1"
    //         }
    // }
	url:=g.Url.BaseTradeUrl+"balances"
	res,err:=http.Post(url,"header",strings.NewReader("name=cjb"))
	
	if err!=nil{
		fmt.Println("请求c2c深度网址返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求c2c深度正确返回",string(body))
}

// 下单函数-买
func (g *Gateio)buy(){
	// {
	// 	"result":"true",
	// 	"orderNumber":"123456",
	// 	"rate":"1000",
	// 	"leftAmount":"0",
	// 	"filledAmount":"0.1",
	// 	"filledRate":"800.00",
	// 	"message":"Success"
	// }
	url:=g.Url.BaseTradeUrl+"buy"
	res,err:=http.Post(url,"header",strings.NewReader("name=cjb"))
	
	if err!=nil{
		fmt.Println("请求下买单网址返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求下单买单正确返回",string(body))

}

// 下单函数-卖
func (g *Gateio)sell(){
	// {
	// 	"result":"true",
	// 	"orderNumber":"123456",
	// 	"rate":"1000",
	// 	"leftAmount":"0",
	// 	"filledAmount":"0.1",
	// 	"filledRate":"800.00",
	// 	"message":"Success"
	// }
	url:=g.Url.BaseTradeUrl+"sell"
	res,err:=http.Post(url,"header",strings.NewReader("name=cjb"))
	
	if err!=nil{
		fmt.Println("请求下单卖单网址返回报错",err)
	}
	defer res.Body.Close()
	body,err:=ioutil.ReadAll(res.Body)
	fmt.Println("请求下单卖单正确返回",string(body))
}

// 运行
func run(){
	gate:=new(Gateio)
	gate.initURL()
	gate.getThePairs()
}